package router

import (
	"gdshop-back-end-go/common/response"
	"github.com/gogf/gf/net/ghttp"
	"reflect"
)

// 调用方法
func methodCall(r *ghttp.Request, version string, controller interface{}, methodName string) {
	t := reflect.ValueOf(controller)
	// 获取当前需要执行的方法
	currentMethod := t.MethodByName(methodName)
	// 判断方法是否存在
	if !currentMethod.IsValid() {
		// 清除输出的信息
		r.Response.ClearBuffer()
		response.JsonExit(r, 1, version+" 不存在该方法，请确认后重新提交")
		return
	}
	// 执行的参数，既是 请求
	args := []reflect.Value{reflect.ValueOf(r)}
	// 前置方法
	initMethod := t.MethodByName("Init")
	if initMethod.IsValid() {
		jieguo := initMethod.Call(args)[0].Interface().(*response.JsonResponse)
		if jieguo.Code != 0 {
			response.JsonExit(r, jieguo.Code, jieguo.Message)
			return
		}
	}
	// 执行当前URL方法
	jsonResp := currentMethod.Call(args)[0].Interface().(*response.JsonResponse)
	jsonResp.Version = version
	r.Response.WriteJson(jsonResp)
	// 后置方法
	shutMethod := t.MethodByName("Shut")
	if shutMethod.IsValid() {
		jieguo := shutMethod.Call(args)[0].Interface().(*response.JsonResponse)
		if jieguo.Code != 0 {
			// 清除输出的信息
			r.Response.ClearBuffer()
			response.JsonExit(r, jieguo.Code, jieguo.Message)
			return
		}
	}
}

// 绑定处理方法和版本
func BindHandlerVersion(r *ghttp.Request, versionName string,
	controllerMaps map[string]interface{},
	defaultVersionName string, methodName string) {
	// 如果 controllerMaps 赋值长度只有一个，直接调用
	if len(controllerMaps) == 1 {
		methodCall(r, defaultVersionName, controllerMaps[defaultVersionName], methodName)
	} else {
		version := response.GetVersion(r, versionName)
		// 如果未传 version ，则使用默认的版本
		if version == "" {
			version = defaultVersionName
		}
		//
		controller, exists := controllerMaps[version]
		if !exists {
			// 不存在版本，使用默认版本
			controller, exists := controllerMaps[defaultVersionName]
			if !exists {
				response.JsonExit(r, 1, "版本不存在并且默认版本也不存在")
			} else {
				r.Header.Add(versionName, defaultVersionName)
				// 使用默认版本传入
				methodCall(r, defaultVersionName, controller, methodName)
			}
			return
		} else {
			methodCall(r, version, controller, methodName)
		}
	}
}
